package smartbooks.ui.customers;

import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.HashSet;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
import smartbooks.ui.manager.CustomerManager;
import smartbooks.ui.manager.InvoiceManager;
import static smartbooks.ui.util.CommonConstants.DEFAULT_BILLTO_CITY;
import static smartbooks.ui.util.CommonConstants.DEFAULT_BILLTO_STATE;
import static smartbooks.ui.util.CommonConstants.stateCityMapping;
import smartbooks.ui.util.CommonFunctions;
import smartbooksdb.hibernatebean.Customer;

/**
 *
 * @author Ankit
 */
public class CustomersListPanel extends javax.swing.JPanel {
    ArrayList<Customer> customers = new ArrayList<>();
    ArrayList<Customer> customersInSearchTable = new ArrayList<>();
    String[] columnNames = {"No","Customer Name","Balance","Phone"};
    ArrayList states = new ArrayList();
    ArrayList cities = new ArrayList();
    
    /**
     * Creates new form CustomersListPanel
     */
    public CustomersListPanel() {
        setAllStates();
        setAllCities();
        
        initComponents();
        
        customInitComponents();
    }
    
    private void setAllStates() {
        this.states.addAll(stateCityMapping.keySet());
        this.states.remove(DEFAULT_BILLTO_STATE);
    }
    
    private void setAllCities() {
        for(ArrayList<String> citiesOfAState : stateCityMapping.values()) {
            this.cities.addAll(citiesOfAState);
        }
        
        HashSet hs = new HashSet();
        hs.addAll(this.cities);
        this.cities.clear();
        this.cities.addAll(hs);
        this.cities.remove(DEFAULT_BILLTO_CITY);
    }
    
    /**
     * This method is used to get States
     * @return states
     */
    public ArrayList getStates() {
        return this.states;
    }
    
    /**
     * This method is used to set States
     * @param states
     */
    public void setStates(ArrayList states) {
        this.states = states;
    }
    
    /**
     * This method is used to get Cities
     * @return cities
     */
    public ArrayList getCities() {
        return this.cities;
    }
    
    /**
     * This method is used to set Cities
     * @param cities
     */
    public void setCities(ArrayList cities) {
        this.cities = cities;
    }
    
    private void customInitComponents() {
        addKeyListenersToComponents(keyListener);
        
        rebuildCustomersListPanel();
    }
    
    private void rebuildCustomersListPanel() {
        setAllCustomers();
        
        String customerNameSearch = (null==customerNameComboBox.getSelectedItem()) ? "" : customerNameComboBox.getSelectedItem().toString();
        String billToStateSearch = (null==billToStateComboBox.getSelectedItem()) ? "" : billToStateComboBox.getSelectedItem().toString();
        String billToCitySearch = (null==billToCityComboBox.getSelectedItem()) ? "" : billToCityComboBox.getSelectedItem().toString();
        String shipToStateSearch = (null==shipToStateComboBox.getSelectedItem()) ? "" : shipToStateComboBox.getSelectedItem().toString();
        String shipToCitySearch = (null==shipToCityComboBox.getSelectedItem()) ? "" : shipToCityComboBox.getSelectedItem().toString();
        
        populateSearchComboBoxes();
        
        customerNameComboBox.setSelectedItem(customerNameSearch);
        billToStateComboBox.setSelectedItem(billToStateSearch);
        billToCityComboBox.setSelectedItem(billToCitySearch);
        shipToStateComboBox.setSelectedItem(shipToStateSearch);
        shipToCityComboBox.setSelectedItem(shipToCitySearch);

        updateCustomersListTable();
    }
    
    private void setAllCustomers() {
        this.customers.clear();
        this.customers = CustomerManager.getAllActiveCustomers();
    }
    
    private void populateSearchComboBoxes() {
        customerNameComboBox.removeAllItems();
        billToStateComboBox.removeAllItems();
        billToCityComboBox.removeAllItems();
        shipToStateComboBox.removeAllItems();
        shipToCityComboBox.removeAllItems();
        
        for(Customer customer : customers) {
            if(null!=customer.getCustomerName() && !customer.getCustomerName().equals("")) {
                customerNameComboBox.addItem(new MyComboBoxItem(customer.getCustomerName()));
            }
        }
        
        billToStateComboBox.setModel(new DefaultComboBoxModel(this.states.toArray()));
        billToCityComboBox.setModel(new DefaultComboBoxModel(this.cities.toArray()));
        shipToStateComboBox.setModel(new DefaultComboBoxModel(this.states.toArray()));
        shipToCityComboBox.setModel(new DefaultComboBoxModel(this.cities.toArray()));
        
        customerNameComboBox.setSelectedIndex(-1);
        billToStateComboBox.setSelectedIndex(-1);
        billToCityComboBox.setSelectedIndex(-1);
        shipToStateComboBox.setSelectedIndex(-1);
        shipToCityComboBox.setSelectedIndex(-1);
    }
    
    private void updateCustomersListTable() {
        ArrayList<ArrayList<String>> customersList = new ArrayList<ArrayList<String>>();
        
        String customerNameSearch = (null==customerNameComboBox.getSelectedItem()) ? "" : customerNameComboBox.getSelectedItem().toString().trim().toUpperCase();
        String billToStateSearch = (null==billToStateComboBox.getSelectedItem()) ? "" : billToStateComboBox.getSelectedItem().toString().trim().toUpperCase();
        String billToCitySearch = (null==billToCityComboBox.getSelectedItem()) ? "" : billToCityComboBox.getSelectedItem().toString().trim().toUpperCase();
        String shipToStateSearch = (null==shipToStateComboBox.getSelectedItem()) ? "" : shipToStateComboBox.getSelectedItem().toString().trim().toUpperCase();
        String shipToCitySearch = (null==shipToCityComboBox.getSelectedItem()) ? "" : shipToCityComboBox.getSelectedItem().toString().trim().toUpperCase();
        
        customersInSearchTable.clear();
        int i = 1;
        for(Customer customer : customers) {
            if(!customerNameSearch.equals("") && null!=customer.getCustomerName() && customer.getCustomerName().toUpperCase().contains(customerNameSearch)) {
                customersList.add(putCustomerDataIntoList(customer,i++));
                customersInSearchTable.add(customer);
            } else if(!billToStateSearch.equals("") && null!=customer.getBillToState()&& customer.getBillToState().toUpperCase().contains(billToStateSearch)) {
                customersList.add(putCustomerDataIntoList(customer,i++));
                customersInSearchTable.add(customer);
            } else if(!billToCitySearch.equals("") && null!=customer.getBillToCity()&& customer.getBillToCity().toUpperCase().contains(billToCitySearch)) {
                customersList.add(putCustomerDataIntoList(customer,i++));
                customersInSearchTable.add(customer);
            } else if(!shipToStateSearch.equals("") && null!=customer.getShipToState()&& customer.getShipToState().toUpperCase().contains(shipToStateSearch)) {
                customersList.add(putCustomerDataIntoList(customer,i++));
                customersInSearchTable.add(customer);
            } else if(!shipToCitySearch.equals("") && null!=customer.getShipToCity()&& customer.getShipToCity().toUpperCase().contains(shipToCitySearch)) {
                customersList.add(putCustomerDataIntoList(customer,i++));
                customersInSearchTable.add(customer);
            } else if(customerNameSearch.equals("") && billToStateSearch.equals("") && billToCitySearch.equals("") && shipToStateSearch.equals("") && shipToCitySearch.equals("")) {
                customersList.add(putCustomerDataIntoList(customer,i++));
                customersInSearchTable.add(customer);
            }
        }
        
        ArrayList<String[]> tempList = new ArrayList<String[]>();
        for (ArrayList<String> stringList : customersList){
            tempList.add((String[])stringList.toArray(new String[0]));
        }
        
        String[][] customersListInTable = (String[][])tempList.toArray(new String[0][]);
        
        customersListTable.setModel(new DefaultTableModel(customersListInTable,columnNames) {
            @Override
            public boolean isCellEditable(int row, int column) {
                return false;
            }
        });
        
        customersListTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {    
            @Override
            public void valueChanged(ListSelectionEvent e) {
                if(!e.getValueIsAdjusting()) {
                    deleteCustomerButton.setEnabled(customersListTable.getSelectedRows().length>=1);
                    editCustomerButton.setEnabled(customersListTable.getSelectedRows().length==1);
                }
            }
        }); 
        
        initColumnSizes();
    }
    
    private void initColumnSizes() {
        double[] columnSizes = {0.01,0.50,0.24,0.25};
        Dimension tableSize =  customersListTable.getPreferredSize();
        
        for(int i=0; i<customersListTable.getColumnCount(); i++) {
            customersListTable.getColumnModel().getColumn(i).setPreferredWidth((int) Math.round(tableSize.width*columnSizes[i]));
        }
    }
    
    private ArrayList<String> putCustomerDataIntoList(Customer customer, int no) {
        ArrayList<String> customerList = new ArrayList<String>();
        
        customerList.add(String.valueOf(no));
        customerList.add(customer.getCustomerName());
        customerList.add(InvoiceManager.getBalanceByCustomerId(customer.getCustomerId()));
        customerList.add(customer.getPhone());
        
        return customerList;
    }
    
    private void addKeyListenersToComponents(KeyListener keyListener) {
        ((JTextField)customerNameComboBox.getEditor().getEditorComponent()).addKeyListener(keyListener);
        ((JTextField)billToStateComboBox.getEditor().getEditorComponent()).addKeyListener(keyListener);
        ((JTextField)billToCityComboBox.getEditor().getEditorComponent()).addKeyListener(keyListener);
        ((JTextField)shipToStateComboBox.getEditor().getEditorComponent()).addKeyListener(keyListener);
        ((JTextField)shipToCityComboBox.getEditor().getEditorComponent()).addKeyListener(keyListener);
    }
    
    private static class MyComboBoxItem {
        private String value;

        public MyComboBoxItem(String value) {
            this.value = value;
        }

        public String getValue() {
            return value;
        }

        @Override
        public String toString() {
            return value; //this is what display in the JComboBox
        }
    }
    
    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        statementPopupMenu = new javax.swing.JPopupMenu();
        printMenuItem = new javax.swing.JMenuItem();
        printPreviewMenuItem = new javax.swing.JMenuItem();
        emailMenuItem = new javax.swing.JMenuItem();
        faxMenuItem = new javax.swing.JMenuItem();
        saveAsPDFMenuItem = new javax.swing.JMenuItem();
        customersListPanel = new javax.swing.JPanel();
        customersListToolBar = new javax.swing.JToolBar();
        addCustomerButton = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        deleteCustomerButton = new javax.swing.JButton();
        jLabel2 = new javax.swing.JLabel();
        editCustomerButton = new javax.swing.JButton();
        jLabel4 = new javax.swing.JLabel();
        jSeparator1 = new javax.swing.JToolBar.Separator();
        jLabel9 = new javax.swing.JLabel();
        invoiceButton = new javax.swing.JButton();
        jLabel5 = new javax.swing.JLabel();
        paymentButton = new javax.swing.JButton();
        jLabel8 = new javax.swing.JLabel();
        statementButton = new javax.swing.JButton();
        jPanel2 = new javax.swing.JPanel();
        jLabel3 = new javax.swing.JLabel();
        customerNameComboBox = new javax.swing.JComboBox();
        billingPanel = new javax.swing.JPanel();
        jLabel6 = new javax.swing.JLabel();
        billToStateComboBox = new javax.swing.JComboBox();
        jLabel7 = new javax.swing.JLabel();
        billToCityComboBox = new javax.swing.JComboBox();
        shippingPanel = new javax.swing.JPanel();
        jLabel10 = new javax.swing.JLabel();
        shipToStateComboBox = new javax.swing.JComboBox();
        jLabel11 = new javax.swing.JLabel();
        shipToCityComboBox = new javax.swing.JComboBox();
        resetButton = new javax.swing.JButton();
        searchButton = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        customersListTable = new javax.swing.JTable();

        printMenuItem.setText("Print");
        statementPopupMenu.add(printMenuItem);

        printPreviewMenuItem.setText("Print Preview");
        statementPopupMenu.add(printPreviewMenuItem);

        emailMenuItem.setText("Email");
        statementPopupMenu.add(emailMenuItem);

        faxMenuItem.setText("Fax");
        statementPopupMenu.add(faxMenuItem);

        saveAsPDFMenuItem.setText("Save as PDF");
        statementPopupMenu.add(saveAsPDFMenuItem);

        customersListPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Customers List", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 14))); // NOI18N

        customersListToolBar.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        customersListToolBar.setFloatable(false);
        customersListToolBar.setRollover(true);

        addCustomerButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        addCustomerButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/smartbooks/images/add_24-24.png"))); // NOI18N
        addCustomerButton.setText("Add");
        addCustomerButton.setFocusable(false);
        addCustomerButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        addCustomerButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        addCustomerButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addCustomerButtonActionPerformed(evt);
            }
        });
        customersListToolBar.add(addCustomerButton);

        jLabel1.setText("   ");
        customersListToolBar.add(jLabel1);

        deleteCustomerButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        deleteCustomerButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/smartbooks/images/delete_24-24.png"))); // NOI18N
        deleteCustomerButton.setText("Delete");
        deleteCustomerButton.setEnabled(false);
        deleteCustomerButton.setFocusable(false);
        deleteCustomerButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        deleteCustomerButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        deleteCustomerButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                deleteCustomerButtonActionPerformed(evt);
            }
        });
        customersListToolBar.add(deleteCustomerButton);

        jLabel2.setText("   ");
        customersListToolBar.add(jLabel2);

        editCustomerButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        editCustomerButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/smartbooks/images/edit_24-24.png"))); // NOI18N
        editCustomerButton.setText("Edit");
        editCustomerButton.setEnabled(false);
        editCustomerButton.setFocusable(false);
        editCustomerButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        editCustomerButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        editCustomerButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                editCustomerButtonActionPerformed(evt);
            }
        });
        customersListToolBar.add(editCustomerButton);

        jLabel4.setText("   ");
        customersListToolBar.add(jLabel4);
        customersListToolBar.add(jSeparator1);

        jLabel9.setText("   ");
        customersListToolBar.add(jLabel9);

        invoiceButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        invoiceButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/smartbooks/images/invoice_24-24.png"))); // NOI18N
        invoiceButton.setText("Invoice");
        invoiceButton.setFocusable(false);
        invoiceButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        invoiceButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        customersListToolBar.add(invoiceButton);

        jLabel5.setText("   ");
        customersListToolBar.add(jLabel5);

        paymentButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        paymentButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/smartbooks/images/payment_24-24.png"))); // NOI18N
        paymentButton.setText("Payment");
        paymentButton.setFocusable(false);
        paymentButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        paymentButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        customersListToolBar.add(paymentButton);

        jLabel8.setText("   ");
        customersListToolBar.add(jLabel8);

        statementButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        statementButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/smartbooks/images/statement_24-24.png"))); // NOI18N
        statementButton.setText("Statement");
        statementButton.setFocusable(false);
        statementButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        statementButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        statementButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                statementButtonActionPerformed(evt);
            }
        });
        customersListToolBar.add(statementButton);

        jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Search Criteria", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N

        jLabel3.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jLabel3.setText("Customer:");

        customerNameComboBox.setEditable(true);
        customerNameComboBox.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N

        billingPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Billing", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N

        jLabel6.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jLabel6.setText("State:");

        billToStateComboBox.setEditable(true);
        billToStateComboBox.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N

        jLabel7.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jLabel7.setText("City:");

        billToCityComboBox.setEditable(true);
        billToCityComboBox.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N

        javax.swing.GroupLayout billingPanelLayout = new javax.swing.GroupLayout(billingPanel);
        billingPanel.setLayout(billingPanelLayout);
        billingPanelLayout.setHorizontalGroup(
            billingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(billingPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(billingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel6, javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel7, javax.swing.GroupLayout.Alignment.TRAILING))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(billingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(billToStateComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 196, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(billToCityComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        billingPanelLayout.setVerticalGroup(
            billingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(billingPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(billingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                    .addComponent(jLabel6)
                    .addComponent(billToStateComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(billingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                    .addComponent(jLabel7)
                    .addComponent(billToCityComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        shippingPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Shipping", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N

        jLabel10.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jLabel10.setText("State:");

        shipToStateComboBox.setEditable(true);
        shipToStateComboBox.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N

        jLabel11.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jLabel11.setText("City:");

        shipToCityComboBox.setEditable(true);
        shipToCityComboBox.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N

        javax.swing.GroupLayout shippingPanelLayout = new javax.swing.GroupLayout(shippingPanel);
        shippingPanel.setLayout(shippingPanelLayout);
        shippingPanelLayout.setHorizontalGroup(
            shippingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(shippingPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(shippingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel10, javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel11, javax.swing.GroupLayout.Alignment.TRAILING))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(shippingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(shipToStateComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 196, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(shipToCityComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        shippingPanelLayout.setVerticalGroup(
            shippingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(shippingPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(shippingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                    .addComponent(jLabel10)
                    .addComponent(shipToStateComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(shippingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                    .addComponent(jLabel11)
                    .addComponent(shipToCityComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        resetButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        resetButton.setText("Reset");
        resetButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                resetButtonActionPerformed(evt);
            }
        });

        searchButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        searchButton.setText("Search");
        searchButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                searchButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addComponent(resetButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(searchButton))
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel2Layout.createSequentialGroup()
                                .addComponent(jLabel3)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(customerNameComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 198, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addComponent(billingPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(shippingPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        jPanel2Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {resetButton, searchButton});

        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                    .addComponent(jLabel3)
                    .addComponent(customerNameComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(shippingPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(billingPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(searchButton)
                    .addComponent(resetButton))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        customersListTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "No", "Customer Name", "Balance", "Phone"
            }
        ) {
            boolean[] canEdit = new boolean [] {
                false, false, false, false
            };

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        customersListTable.setFocusable(false);
        customersListTable.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                customersListTableMouseClicked(evt);
            }
        });
        jScrollPane1.setViewportView(customersListTable);

        javax.swing.GroupLayout customersListPanelLayout = new javax.swing.GroupLayout(customersListPanel);
        customersListPanel.setLayout(customersListPanelLayout);
        customersListPanelLayout.setHorizontalGroup(
            customersListPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(customersListPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(customersListPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(customersListToolBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jScrollPane1))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        customersListPanelLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {customersListToolBar, jPanel2, jScrollPane1});

        customersListPanelLayout.setVerticalGroup(
            customersListPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(customersListPanelLayout.createSequentialGroup()
                .addComponent(customersListToolBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 269, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(customersListPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(customersListPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        );
    }// </editor-fold>//GEN-END:initComponents

    private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchButtonActionPerformed
        updateCustomersListTable();
    }//GEN-LAST:event_searchButtonActionPerformed

    private void resetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_resetButtonActionPerformed
        customerNameComboBox.setSelectedItem("");
        billToStateComboBox.setSelectedItem("");
        billToCityComboBox.setSelectedItem("");
        shipToStateComboBox.setSelectedItem("");
        shipToCityComboBox.setSelectedItem("");

        updateCustomersListTable();
    }//GEN-LAST:event_resetButtonActionPerformed

    private void addCustomerButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addCustomerButtonActionPerformed
        CustomersDialog customersDialog = new CustomersDialog(CommonFunctions.getParentJFrame(this), true, null);
        Customer customer = customersDialog.showDialog();
        if(null!=customer) {
            rebuildCustomersListPanel();
        }
    }//GEN-LAST:event_addCustomerButtonActionPerformed

    private void deleteCustomerButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteCustomerButtonActionPerformed
        int deleteConfirmation = JOptionPane.showConfirmDialog(this, "Are you sure you want to delete the selected customer(s) ?", "SmartBooks - Confirmation", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);

        if(deleteConfirmation==0) {
            for(int row : customersListTable.getSelectedRows()) {
                CustomerManager.deleteCustomer(customersInSearchTable.get(row));
            }
            
            rebuildCustomersListPanel();
            
            JOptionPane.showMessageDialog(this,"Customer(s) is/are deleted successfully !","SmartBooks - Success",JOptionPane.INFORMATION_MESSAGE);
        }
    }//GEN-LAST:event_deleteCustomerButtonActionPerformed

    private void editCustomerButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editCustomerButtonActionPerformed
        int selectedRow = customersListTable.getSelectedRow();
        
        if(selectedRow>=0) {
            Customer selectedCustomer = (customersInSearchTable.get(selectedRow)).clone();
            CustomersDialog customersDialog = new CustomersDialog(CommonFunctions.getParentJFrame(this), true, selectedCustomer);
            Customer customer = customersDialog.showDialog();
            if(null!=customer) {
                rebuildCustomersListPanel();
            }
        } else {
            JOptionPane.showMessageDialog(this,"No row is selected to edit customer !","SmartBooks - Warning",JOptionPane.WARNING_MESSAGE);
        }
    }//GEN-LAST:event_editCustomerButtonActionPerformed

    private void customersListTableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_customersListTableMouseClicked
        if(evt.getClickCount()==2) {
            editCustomerButtonActionPerformed(null);
        }
    }//GEN-LAST:event_customersListTableMouseClicked

    private void statementButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_statementButtonActionPerformed
        statementPopupMenu.show(statementButton, statementButton.getWidth()/2, statementButton.getHeight()/2);
    }//GEN-LAST:event_statementButtonActionPerformed


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addCustomerButton;
    private javax.swing.JComboBox billToCityComboBox;
    private javax.swing.JComboBox billToStateComboBox;
    private javax.swing.JPanel billingPanel;
    private javax.swing.JComboBox customerNameComboBox;
    private javax.swing.JPanel customersListPanel;
    private javax.swing.JTable customersListTable;
    private javax.swing.JToolBar customersListToolBar;
    private javax.swing.JButton deleteCustomerButton;
    private javax.swing.JButton editCustomerButton;
    private javax.swing.JMenuItem emailMenuItem;
    private javax.swing.JMenuItem faxMenuItem;
    private javax.swing.JButton invoiceButton;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JToolBar.Separator jSeparator1;
    private javax.swing.JButton paymentButton;
    private javax.swing.JMenuItem printMenuItem;
    private javax.swing.JMenuItem printPreviewMenuItem;
    private javax.swing.JButton resetButton;
    private javax.swing.JMenuItem saveAsPDFMenuItem;
    private javax.swing.JButton searchButton;
    private javax.swing.JComboBox shipToCityComboBox;
    private javax.swing.JComboBox shipToStateComboBox;
    private javax.swing.JPanel shippingPanel;
    private javax.swing.JButton statementButton;
    private javax.swing.JPopupMenu statementPopupMenu;
    // End of variables declaration//GEN-END:variables

    KeyListener keyListener = new KeyListener() {

        @Override
        public void keyTyped(KeyEvent e) { }

        @Override
        public void keyPressed(KeyEvent e) { }

        @Override
        public void keyReleased(KeyEvent e) {
            if(e.getKeyCode() == KeyEvent.VK_ENTER) { 
                searchButtonActionPerformed(null);
            }
        }
    };
}